'use strict'

const fs = require('fs')
const os = require('os')
const path = require('path')

const { UNVALIDATED_REDIRECT } = require('../../../../src/appsec/iast/vulnerabilities')
const { prepareTestServerForIastInExpress } = require('../utils')
const { withVersions } = require('../../../setup/mocha')
const axios = require('axios')

describe('Vulnerability Analyzer plugin', () => {
  let redirectFunctions
  let redirectMinFunctions
  const redirectFunctionsFilename = 'redirect-express-functions.js'
  const redirectFunctionsPath = path.join(os.tmpdir(), redirectFunctionsFilename)

  const redirectFunctionsMinFilename = 'redirect-express-functions.min.js'
  const redirectFunctionsMinPath = path.join(os.tmpdir(), redirectFunctionsMinFilename)

  const redirectFunctionsMapFilename = 'redirect-express-functions.min.js.map'
  const redirectFunctionsMapPath = path.join(os.tmpdir(), redirectFunctionsMapFilename)

  before(() => {
    fs.copyFileSync(path.join(__dirname, 'resources', redirectFunctionsFilename), redirectFunctionsPath)

    // remove comment to adjust sourcemap and source file lines
    const fileContent = fs.readFileSync(path.join(__dirname, 'resources', redirectFunctionsMinFilename), 'utf8')
      .replace('/* eslint-disable */\n', '')
    fs.writeFileSync(redirectFunctionsMinPath, fileContent)
    fs.copyFileSync(path.join(__dirname, 'resources', redirectFunctionsMapFilename), redirectFunctionsMapPath)

    redirectFunctions = require(redirectFunctionsPath)
    redirectMinFunctions = require(redirectFunctionsMinPath)
  })

  after(() => {
    fs.unlinkSync(redirectFunctionsPath)
    fs.unlinkSync(redirectFunctionsMinPath)
    fs.unlinkSync(redirectFunctionsMapPath)
  })

  withVersions('express', 'express', version => {
    prepareTestServerForIastInExpress('should find original source line minified or not', version,
      (testThatRequestHasVulnerability, testThatRequestHasNoVulnerability) => {
        testThatRequestHasVulnerability((req, res) => {
          redirectMinFunctions.insecureWithResHeaderMethod('location', req.query.location, res)
        }, UNVALIDATED_REDIRECT, {
          occurrences: 1,
          location: {
            path: redirectFunctionsFilename, // original source code file indicated in sourceMappingURL
            line: 4 // line in not minified source file
          }
        }, null, (done, config) => {
          axios.get(`http://localhost:${config.port}/?location=https://app.com?id=tron`).catch(done)
        })

        testThatRequestHasVulnerability((req, res) => {
          redirectFunctions.insecureWithResHeaderMethod('location', req.query.location, res)
        }, UNVALIDATED_REDIRECT, {
          occurrences: 1,
          location: {
            path: redirectFunctionsFilename,
            line: 4
          }
        }, null, (done, config) => {
          axios.get(`http://localhost:${config.port}/?location=https://app.com?id=tron`).catch(done)
        })
      })
  })
})
